<html>
<head><meta charset="utf-8"><title>Opting into enum layout optimization · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html">Opting into enum layout optimization</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="217818136"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217818136" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Tyson Nottingham <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217818136">(Nov 24 2020 at 21:48)</a>:</h4>
<p>Is there a way to have the compiler optimize the size of this enum to be 4 bytes? I'm willing to give up bits of each variant for a tag, but I'd rather not give up an entire <em>byte</em> of each variant. I'm curious to know if that's what it takes though.</p>
<div class="codehilite"><pre><span></span><code>#[rustc_layout_scalar_valid_range_end(???)]
struct A {
    x: u32
}

#[rustc_layout_scalar_valid_range_end(???)]
struct B {
    x: u32
}

enum E {
    VariantA(A),
    VariantB(B),
}
</code></pre></div>
<p>I played with various <code>rustc_layout_scalar_valid_range_end</code> attribute values on <code>A</code> and <code>B</code>, thinking that might help, but to no avail. I obviously don't know how that attribute works. :)</p>



<a name="217818302"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217818302" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217818302">(Nov 24 2020 at 21:50)</a>:</h4>
<p>No, there's nothing this can do for you, I believe -- we don't support packing into live values</p>



<a name="217818350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217818350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217818350">(Nov 24 2020 at 21:50)</a>:</h4>
<p>i.e., both A and B can't hold a discriminant regardless of how many valid bits they have</p>



<a name="217818400"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217818400" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217818400">(Nov 24 2020 at 21:51)</a>:</h4>
<p>(from the POV of the compiler, obviously, in practice they could)</p>



<a name="217818505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217818505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Tyson Nottingham <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217818505">(Nov 24 2020 at 21:52)</a>:</h4>
<p>K, good to know. Thanks!</p>



<a name="217830269"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217830269" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217830269">(Nov 25 2020 at 00:03)</a>:</h4>
<p><span class="user-mention" data-user-id="306073">@Tyson Nottingham</span> The core problem here is that you can get a <code>&amp;mut B</code> or a <code>&amp;mut A</code> into that enum, and any write into that will overwrite the full 4 bytes, so there isn't actually anywhere to hide a discriminant.</p>
<p>Making that work would need a new "you can't get references to the fields" feature so that the discriminant could always be masked-away on reads or or'ed-back-in on writes.</p>
<p>(Strawman <code>enum E { VariantA(move A), VariantB(move V) }</code> or whatever.)</p>



<a name="217831057"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217831057" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Tyson Nottingham <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217831057">(Nov 25 2020 at 00:13)</a>:</h4>
<p>Gotcha, thanks for the explanation</p>



<a name="217835423"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217835423" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217835423">(Nov 25 2020 at 01:21)</a>:</h4>
<p>(I guess it could theoretically work -- dunno if it does today -- if they're distinct value ranges.  But if you want them both to allow <code>0</code>, it can't work so long as references are allowed.)</p>



<a name="217836232"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Opting%20into%20enum%20layout%20optimization/near/217836232" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Opting.20into.20enum.20layout.20optimization.html#217836232">(Nov 25 2020 at 01:36)</a>:</h4>
<p><span class="user-mention" data-user-id="125270">@scottmcm</span> even just reads are problematic because if you have a &amp;T you don't know if it's part of the enum or not</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>